#!/usr/bin/python3.6
import cgi
import cgitb
import sqlite3
from collections import defaultdict

from color import str_color
from quote import Quote
from sanitize import sanitize_html
from templating import render

cgitb.enable()

print("Content-type: text/html\n")

form = cgi.FieldStorage()
filter_author = form.getfirst("filter-author", "")
filter_author_lower = filter_author.lower()
x_axis = form.getfirst("x-axis", "author")
y_axis = form.getfirst("y-axis", "num-quotes")
sorting = form.getfirst("sorting", "x")

connection = sqlite3.connect("quotes.sqlite")
cursor = connection.cursor()

query = f"SELECT {','.join(Quote.columns)} FROM quotes"
query_args = []
if filter_author:
    query += " WHERE INSTR(author, ?) <> 0"
    query_args.append(filter_author)
cursor.execute(query, query_args)
quotes = [Quote.from_row(row) for row in cursor.fetchall()]

names = set()
cursor.execute("SELECT DISTINCT author FROM quotes")
names |= {name for (name,) in cursor.fetchall()}
cursor.execute("SELECT DISTINCT writer FROM quotes")
names |= {name for (name,) in cursor.fetchall()}

connection.close()

x_func = {
    "author": lambda quote: quote.author.name,
    "month": lambda quote: quote.datetime.strftime("%Y-%m"),
    "year": lambda quote: quote.datetime.strftime("%Y"),
    "weekday": lambda quote: quote.datetime.strftime("%A"),
    "writer": lambda quote: quote.writer.name,
}[x_axis]
buckets = defaultdict(list)
for quote in quotes:
    try:
        buckets[x_func(quote)].append(quote)
    except AttributeError:
        pass
y_func = {"num-quotes": lambda quotes: len(quotes)}[y_axis]
values = {x: y_func(quotes) for x, quotes in buckets.items()}

max_bar_height = 16
normalizing_factor = 1 / max(values.values())
data = ""
sorting_func = {
    "x": lambda pair: pair[0],
    "y": lambda pair: -pair[1],
}[sorting]
sorted_values = sorted(values.items(), key=sorting_func)
for x, y in sorted_values:
    color = str_color(x)
    size = normalizing_factor * y
    x_cell = f'<th scope="row">{sanitize_html(x)}</th>'
    y_cell = f'<td style="--color:{color};--size:{size}">{sanitize_html(str(y))}</td>'
    data += f"<tr>{x_cell}{y_cell}</tr>"


with open("templates/stats.html", encoding="utf-8") as file:
    template = file.read()
print(
    render(
        template,
        {
            "data": data,
            "filter_author": sanitize_html(filter_author),
            "people_names_datalist": '<datalist id="people-names">'
            + "".join(f'<option value="{sanitize_html(name)}" />' for name in names)
            + "</datalist>",
            "sorting_x": "checked" * (sorting == "x"),
            "sorting_y": "checked" * (sorting == "y"),
            **{
                "x_" + option: "selected" * (x_axis == option)
                for option in ["author", "month", "year", "weekday", "writer"]
            },
        },
    )
    .encode("ascii", "xmlcharrefreplace")
    .decode("ascii")
)
